package calculator;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Arrays;


public class View implements ActionListener, MouseListener {

    private final JFrame frame = new JFrame();

    private final Calculator calculator = new Calculator();

    Color common = new Color(181, 181, 181);  //功能键和运算符颜色
    Color enter = new Color(172, 172, 172);
    Color equal = new Color(126, 192, 238);  //等于号专属颜色
    Color background = new Color(232, 232, 232);  //背景颜色

    private static final String[] keys = {
            "Log","Abs","C","Del",
            "Sin","Cos","Tan","!",
            "(",")",
            "Mod","√","^","÷",
            "7","8","9","×",
            "4","5","6","-",
            "1","2", "3","+",
            "0", ".","="};
    private final JButton[] buttons = new JButton[keys.length];  //计算器上按键的按钮
    private final JTextField resultText = new JTextField("0");  //显示计算结果文本框

    public View() {
        init();  // 初始化计算器
        frame.setTitle("计算器");
        frame.setSize(400, 550);
        frame.setResizable(true);  // 允许修改计算器窗口的大小
        frame.setLocation(200,200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * 初始化计算器
     */
    private void init() {


        // 建立一个画板放文本框
        JPanel textPanel = new JPanel();
        textPanel.setLayout(new BorderLayout());
        textPanel.add(resultText);
        resultText.setFont(new Font("楷体",Font.BOLD,17));  //设置文本框中文字的字体以及大小，加粗
        resultText.setHorizontalAlignment(JTextField.SOUTH_EAST);  //文本框中的内容采用右对齐方式
        resultText.setEditable(false);  //不能修改结果文本框
        resultText.setBorder(null);  //删除文本框的边框
        resultText.setBackground(common);


        GridBagLayout gridBagLayout = new GridBagLayout();
        GridBagConstraints constraints = null;
        JPanel keysPanel = new JPanel(gridBagLayout);

        for(int i = 0; i < 14; i++) {
            buttons[i] = new JButton(keys[i]);
            buttons[i].setBackground(background);
            buttons[i].setForeground(Color.black);
            buttons[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18));
            buttons[i].setBorderPainted(false);
            buttons[i].setFocusPainted(false);
        }

        for(int i = 14; i < keys.length; i++) {
            buttons[i] = new JButton(keys[i]);
            if((i+1)%4==2) buttons[i].setBackground(background);
            else buttons[i].setBackground(Color.white);
            buttons[i].setForeground(Color.black);
            buttons[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18));
            buttons[i].setBorderPainted(false);
            buttons[i].setFocusPainted(false);

        }

        buttons[keys.length - 1].setBackground(equal);  // '='符键用特殊颜色
        keysPanel.setBackground(common);


        for (int i = 0; i < 8; i++) {

            constraints = new GridBagConstraints();
            constraints.fill = GridBagConstraints.BOTH;
            constraints.insets = new Insets(0,i%4==0?0:2,2,0);
            constraints.weightx = 1;
            constraints.weighty = 1;
            if (i%4==3){
                constraints.gridwidth = GridBagConstraints.REMAINDER;
            }
            gridBagLayout.addLayoutComponent(buttons[i],constraints);

        }


        constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weighty = 1;
        constraints.gridwidth = 2;
        constraints.insets = new Insets(0,0,2,0);
        gridBagLayout.addLayoutComponent(buttons[8],constraints);

        constraints = new GridBagConstraints();
        constraints.gridwidth =  GridBagConstraints.REMAINDER;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weighty = 1;
        constraints.insets = new Insets(0,2,2,0);
        gridBagLayout.addLayoutComponent(buttons[9],constraints);

        for (int i = 10;i < 26;i++){
            constraints = new GridBagConstraints();
            constraints.fill = GridBagConstraints.BOTH;
            constraints.insets = new Insets(0,i%4==2?0:2,2,0);
            constraints.weightx = 1;
            constraints.weighty = 1;
            if (i%4==1){
                constraints.gridwidth = GridBagConstraints.REMAINDER;
            }
            gridBagLayout.addLayoutComponent(buttons[i],constraints);
        }

        constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weighty = 1;
        constraints.insets = new Insets(0,0,2,0);
        gridBagLayout.addLayoutComponent(buttons[26],constraints);

        constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weighty = 1;
        constraints.insets = new Insets(0,2,2,0);
        gridBagLayout.addLayoutComponent(buttons[27],constraints);
        constraints = new GridBagConstraints();
        constraints.weighty = 1;
        constraints.gridwidth = GridBagConstraints.REMAINDER;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.insets = new Insets(0,2,2,0);
        gridBagLayout.addLayoutComponent(buttons[28],constraints);

        Arrays.stream(buttons).forEach(keysPanel::add);


        gridBagLayout = new GridBagLayout();
        frame.setLayout(gridBagLayout);

        constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weighty = 0.5;
        constraints.weightx = 1;
        constraints.insets = new Insets(0,1,0,1);
        constraints.gridwidth = GridBagConstraints.REMAINDER;
        gridBagLayout.addLayoutComponent(textPanel,constraints);

        constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weighty = 1;
        constraints.weightx = 1;
        constraints.insets = new Insets(0,1,0,1);
        gridBagLayout.addLayoutComponent(keysPanel,constraints);

        frame.add(textPanel);
        frame.add(keysPanel);
        //设置两个面板的边框，尽量还原win10计算器
        textPanel.setBorder(BorderFactory.createMatteBorder(25,3,1,3,common));
        keysPanel.setBorder(BorderFactory.createMatteBorder(6,3,3,3,common));

        // 为各按钮添加事件监听器，都使用同一个事件监听器。
        for (int i = 0; i < keys.length; i++) {
            buttons[i].addActionListener(this);
            buttons[i].addMouseListener(this);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();  // 获取事件源


        for (String key: keys){

            if (command.equals("Log")){
                input("㏒");
                return;
            }

            if (command.equals("Abs")){
                input("|");
                return;
            }

            if (command.equals("C")){
                clear();
                return;
            }

            if (command.equals("Del")){
                del();
                return;
            }

            if (command.equals("Sin")){
                input("s");
                return;
            }
            if (command.equals("Cos")){
                input("c");
                return;
            }
            if (command.equals("Tan")){
                input("t");
                return;
            }

            if (command.equals("Mod")){
                input("%");
                return;
            }

            if (command.equals("=")){
                String expr = resultText.getText();

                if (expr.equals("0")){
                    return;
                }

                double result = calculator.calculate(expr);

                resultText.setText(expr+" = "+result);
                return;
            }


            if (command.equals(key)){
                input(command);
            }
        }
    }

    private void clear(){
        resultText.setText("0");
    }

    private void input(String key) {
        if (resultText.getText().equals("0")){
            resultText.setText(key);
            return;
        }
        resultText.setText(resultText.getText() + key);
    }

    private void del() {
        String text = resultText.getText();
        int i = text.length();
        if (i > 0) {
            text = text.substring(0, i - 1);
            if (text.length() == 0) {
                resultText.setText("0");
            } else {
                resultText.setText(text);
            }
        }
    }

    public static void main(String[] args) {
        new View();
    }


    @Override
    public void mouseClicked(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        JButton button = (JButton) e.getSource();
        button.setBackground(new Color(206, 206, 206));
    }

    @Override
    public void mouseExited(MouseEvent e) {
        JButton button = (JButton) e.getSource();

        if (button.getText().equals("=")){
            button.setBackground(equal);
            return;
        }

        char c = button.getText().charAt(0);

        if (c >= '0' && c <= '9' || c == '.'){
            button.setBackground(Color.white);
            return;
        }

        button.setBackground(background);
    }
}
